﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Noris.Schedule.Support.Green;
using Noris.Schedule.Support.Sql;
using Noris.Tools.FrxEditor.Data;
using Noris.Tools.FrxEditor.Components;


namespace Noris.Tools.FrxEditor.Forms
{
    /// <summary>
    /// Testovací formulář
    /// </summary>
	public partial class ClassTreeFilterForm : DForm
	{
        /// <summary>
        /// Testovací formulář, konstruktor
        /// </summary>
        public ClassTreeFilterForm()
		{
			InitializeComponent();
            InitTree();
            InitCombo();
            FillClasses(1188);
		}
        /// <summary>
        /// Konfigurace
        /// </summary>
        protected override int[] ConfigUserData
        {
            set
            {
                if (value.Length >= 3)
                {
                    this.SplitContainer.SplitterPosition = value[0];
                    this.ClassTreePanel.SplitterPosition = value[1];
                    this.SplitSql.SplitterPosition = value[2];
                }
            }
            get
            {   // Při ukončení okna: posbírat rozměry a vrátit jako pole
                int[] data = new int[]
                {
                    this.SplitContainer.SplitterPosition,
                    this.ClassTreePanel.SplitterPosition,
                    this.SplitSql.SplitterPosition
                };
                return data;
            }
        }
        private void InitTree()
        {
            this.ClassTreePanel.RelationToLeftEnabled = true;
            this.ClassTreePanel.AttributeSelect += new Schedule.Support.Components.ClassTreePanelHandler(ClassTreePanel_AttributeSelect);

            this.PanelOK.DirtySensitive = false;
            this.PanelOK.Save += new EventHandler(PanelOK_Save);
        }
        private void InitCombo()
        {
            this.ClassesCombo.Items.Clear();
            this.ClassesCombo.DropDownStyle = ComboBoxStyle.DropDownList;
            this.ClassesCombo.SelectedIndexChanged += new EventHandler(ClassesCombo_SelectedIndexChanged);

            this.FiltersCombo.Items.Clear();
            this.FiltersCombo.DropDownStyle = ComboBoxStyle.DropDownList;
            this.FiltersCombo.SelectedIndexChanged += new EventHandler(FiltersCombo_SelectedIndexChanged);
        }
        private void FillClasses(int classNumber)
        {
            this.ClassesCombo.Items.Clear();
            object selectItem = null;
            IEnumerable<RepositoryTextItem<int>> classes = Repository.Classes.GetAllTexts();
            foreach (RepositoryTextItem<int> item in classes)
            {
                this.ClassesCombo.Items.Add(item);
                if (item.Key == classNumber)
                    selectItem = item;
            }
            if (selectItem != null)
                this.ClassesCombo.SelectedItem = selectItem;            // Vyvolá event ClassesCombo_SelectedIndexChanged: ClassTree se inicializuje pro danou třídu a načtou se filtry.
        }
        private void ClassesCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            RepositoryTextItem<int> selectedClass = this.ClassesCombo.SelectedItem as RepositoryTextItem<int>;
            if (selectedClass == null) return;
            this.Clear();
            this.ClassTreePanel.RootClassNumber = selectedClass.Key;
            this.FillFilter(this.ClassTreePanel.RootClassNumber);
        }
        private void FillFilter(int classNumber)
        {
            string filter = "cislo_tridy=" + classNumber.ToString() + (this.AllFilterChk.Checked ? "" : " and display=1");

            int key = 0;
            RepositoryTextItem<int> selectedItem = this.FiltersCombo.SelectedItem as RepositoryTextItem<int>;
            if (selectedItem != null)
                key = selectedItem.Key;

            this.FiltersCombo.Items.Clear();

            object selectItem = new RepositoryTextItem<int>(0, " Bez filtru");
            this.FiltersCombo.Items.Add(selectItem);
            
            IEnumerable<RepositoryTextItem<int>> classes = Repository.Filters.GetAllTexts(filter);
            foreach (RepositoryTextItem<int> item in classes)
            {
                this.FiltersCombo.Items.Add(item);
                if (selectItem == null || (key != 0 && item.Key == key))
                    selectItem = item;
            }
            if (selectItem != null)
                this.FiltersCombo.SelectedItem = selectItem; 
        }
        private void FiltersCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._LoadDataFromClassTreeFilter();
        }
        private void AllFilterChk_CheckedChanged(object sender, EventArgs e)
        {
            this.FillFilter(this.ClassTreePanel.RootClassNumber);
        }
        private void ShareCheck_CheckedChanged(object sender, EventArgs e)
        {
            this._LoadDataFromClassTreeFilter();
        }
        private void PresetButton_Click(object sender, EventArgs e)
        {
            this.CurrentClass = 210;
            this._SelectedFields = new List<string>();
            this._SelectedFields.Add("C210>Master.reference_subjektu");
            this._SelectedFields.Add("C210>Master.datum");
            this._SelectedFields.Add("C210:R100008:C343>Master.nazev_subjektu");
            this._SelectedFields.Add("C210:R100145:C1268:R9619:C19>Subjekt.nazev_subjektu");
            this._SelectedFields.Add("C210:R1361:C343>Master.reference_subjektu");
            this._SelectedFields.Add("C210:R1361:C343>Master.nazev_subjektu");
            this.CurrentFilter = 1292;
            this._LoadDataFromClassTreeFilter();
        }
        private void ClassTreePanel_AttributeSelect(object sender, Schedule.Support.Components.ClassTreePanelArgs args)
        {
            if (args.SelectedAttributes.Count == 0) return;

            if (this._SelectedFields == null)
                this._SelectedFields = new List<string>();

            foreach (var attr in args.SelectedAttributes)
                this._SelectedFields.Add(attr.FullTreePath);

            this._LoadDataFromClassTreeFilter();
        }
        private int CurrentClass
        {
            get
            {
                RepositoryTextItem<int> selectedItem = this.ClassesCombo.SelectedItem as RepositoryTextItem<int>;
                if (selectedItem == null)
                    return 0;
                return selectedItem.Key;
            }
            set
            {
                foreach (object item in this.ClassesCombo.Items)
                {
                    RepositoryTextItem<int> textItem = item as RepositoryTextItem<int>;
                    if (textItem != null && textItem.Key == value)
                    {
                        this.ClassesCombo.SelectedItem = textItem;
                        break;
                    }
                }
            }
        }
        private int CurrentFilter
        {
            get
            {
                RepositoryTextItem<int> selectedItem = this.FiltersCombo.SelectedItem as RepositoryTextItem<int>;
                if (selectedItem == null)
                    return 0;
                return selectedItem.Key;
            }
            set
            {
                foreach (object item in this.FiltersCombo.Items)
                {
                    RepositoryTextItem<int> textItem = item as RepositoryTextItem<int>;
                    if (textItem != null && textItem.Key == value)
                    {
                        this.FiltersCombo.SelectedItem = textItem;
                        break;
                    }
                }
            }
        }
        private void Clear()
        {
            this._ClassTree = null;
            this._SelectedFields = null;
            this.SqlEditor.EditedText = "";
            this.DataGrid.Clear();
        }
        private void _LoadDataFromClassTreeFilter()
        {
            string sqlSelect = null;
            try
            {
                sqlSelect = this.GetSelect();
                this.SqlEditor.EditedText = sqlSelect;
            }
            catch (Exception exc)
            {
                this.SqlEditor.EditedText = _GetExcInfo("Chyba v ClassTree / Filter: ", exc);
            }

            if (sqlSelect != null)
                this._LoadDataToGrid(sqlSelect);
        }
        private string GetSelect()
        {
            if (this._SelectedFields == null) return "";
            if (this._SelectedFields.Count == 0) return "";

            if (this.ShareCheck.Checked)
                return this.GetSelectShared();
            else
                return this.GetSelectSepared();
        }
        private string GetSelectShared()
        {
            try
            {
                this._ClassTree = new ClassTree();
                this._ClassTree.ColumnAutoAlias = ClassTree.ColumnAutoAliasMode.RelationSuffix;
                this._ClassTree.AliasPrefix = "gs";

                foreach (string attr in this._SelectedFields)
                    this._ClassTree.AddBranchToFinal(attr);

                string fields = this._ClassTree.FinalColumns;

                int filter = this.CurrentFilter;
                string where = null;
                if (filter != 0)
                {
                    this._ClassTree.AliasPrefix = "f" + filter.ToString();
                    where = Repository.Filters.ApplyFilterToClassTree(filter, this._ClassTree);
                }

                string select = "SELECT DISTINCT " + Environment.NewLine + fields + this._ClassTree.AddedTables;

                if (!String.IsNullOrEmpty(where))
                    select += " WHERE " + where;

                return select;
            }
            catch (Exception exc)
            {
                this.SqlEditor.EditedText = _GetExcInfo("Chyba v ClassTree: ", exc);
            }

            return this._ClassTree.SqlSelect;
        }
        private string GetSelectSepared()
        {
            try
            {
                this._ClassTree = new ClassTree();
                this._ClassTree.ColumnAutoAlias = ClassTree.ColumnAutoAliasMode.RelationSuffix;
                this._ClassTree.AliasPrefix = "gs";

                foreach (string attr in this._SelectedFields)
                    this._ClassTree.AddBranchToFinal(attr);

                string select = this._ClassTree.SqlSelect;

                int filter = this.CurrentFilter;
                if (filter != 0)
                    Repository.Filters.ApplyFilterToSelect(filter, ref select);

                return select;
            }
            catch (Exception exc)
            {
                this.SqlEditor.EditedText = _GetExcInfo("Chyba v ClassTree: ", exc);
            }

            return this._ClassTree.SqlSelect;
        }
        private void _LoadDataToGrid(string sqlSelect)
        {
            if (String.IsNullOrEmpty(sqlSelect))
                return;

            try
            {
                string addTop = " top 750";
                string keyword = "SELECT DISTINCT";
                if (sqlSelect.StartsWith(keyword))
                    sqlSelect = keyword + addTop + sqlSelect.Substring(keyword.Length);
                else
                {
                    keyword = "SELECT";
                    if (sqlSelect.StartsWith(keyword))
                        sqlSelect = keyword + addTop + sqlSelect.Substring(keyword.Length);
                }
                sqlSelect += " ORDER BY 1";

                SimpleDataTable dataTable = SimpleDataTable.Load(sqlSelect);
                this.DataGrid.DataTable = dataTable;
            }
            catch (Exception exc)
            {
                this.SqlEditor.EditedText = this.SqlEditor.EditedText + _GetExcInfo("Chyba ve vytvořeném SQL dotazu: ", exc);
            }
        }
        private string _GetExcInfo(string info, Exception exc)
        {
            string text = Environment.NewLine + 
                   Environment.NewLine + 
                   "/* " + Environment.NewLine +
                   info + Environment.NewLine +
                   exc.Message + Environment.NewLine +
                   exc.StackTrace + Environment.NewLine + 
                   "*/";
            return text;
        }
        private void PanelOK_Save(object sender, EventArgs e)
        {
            string sql = @"SELECT 
  p.cislo_subjektu,
  p.cislo_objektu,
  p.cislo_radky,
  f.cislo_tridy,
  cast(1 as int) as data_type,
  p.zdroj source,
  isnull(skl.sklad_mrp,skl.cislo_subjektu) stock,
  p.varianta_zbozi variation,
  p.obchodni_pripad order_relation,
  p.typ,
  p.pocet qty,
  p.pocet_real as qty_realized,
  p.datum date,
  p.datum_plan date_plan,
  p.referencni_cislo reference_number,
  h.sklad2 sklad2,
  f.cislo_poradace,
  f.nazev as folder_nazev,
  h.reference_subjektu,
  h.nazev_subjektu,
  h.organizace,
  org.reference_subjektu as organizace_refer,
  org.nazev_subjektu as organizace_nazev, 
  (select top 1 cislo_objektu from lcs.sk_polozka n where n.pohyb_polozka = p.cislo_objektu and (n.stav = 1 and n.typ = '4')) as vnitropoptavka 
FROM lcs.sk_polozka p
  JOIN lcs.sk_hlavicka h ON h.cislo_subjektu = p.cislo_subjektu
  JOIN lcs.poradace f ON f.cislo_poradace = h.cislo_poradace
  JOIN lcs.sk_sklad skl ON p.sklad=skl.cislo_subjektu
  LEFT OUTER JOIN lcs.subjekty org ON org.cislo_subjektu = h.organizace
WHERE p.stav = '1' and (p.typ = '3' or p.typ = '4' or p.typ = '5') and p.splneno = 'N'
ORDER BY p.cislo_objektu";

            FilterInfo filter = Repository.Filters[1298];
            if (filter == null)
                filter = Repository.Filters[1292];


            if (filter == null)
            {
                MessageBox.Show("Filtr s číslem 1298 neexistuje.");
            }
            else
            {
                _ClassTree = null;
                using (SqlText sqlText = SqlText.CreateFromText(sql))          // Převedu text do parsované podoby, kde s ním lze čarovat
                {
                    SqlParseCommandSelect sqlSel = (SqlParseCommandSelect)sqlText.FindFirstCommand("SELECT");

                    filter.AddExpressionToBegin(1, "lcs.sk_hlavicka.typ", "lcs.sk_hlavicka.typ = '3'", "AND");
                    filter.ApplyFilterToSqlCommand(sqlSel);

                    string sql2 = sqlText.OutputSqlText;
                    this.SqlEditor.EditedText = sql2;
                }
            }


            sql = "select lcs.alfa.beta 12.25";
            Noris.Schedule.Support.Parser.Parser.ChangeTableNameInExpression(sql, this.AliasChanger);


        }
        private string AliasChanger(string input)
        {
            return "";
        }
        private ClassTree _ClassTree;
        private List<string> _SelectedFields;
	}
}
